import * as fs from 'fs-extra';
import * as path from 'path';
import * as sinon from 'sinon';
import { copyDiffFiles } from '../src/copyDiffFiles';
import proxyquire from 'proxyquire'
import {expect} from 'chai'

describe('copyDiffFiles', () => {
    let sandbox: sinon.SinonSandbox;
    let stepMock: any;
    let fsStub:any;

    beforeEach(() => {
        sandbox = sinon.createSandbox();
        stepMock = {
            debug: sandbox.stub(),
            info: sandbox.stub()
        };
        fsStub = {
            readFileSync: sandbox.stub().returns('src/main/java/com/example/MyClass.java'),
            existsSync: sandbox.stub().returns(true),
            copyFileSync: sandbox.stub(),
            mkdirSync: sandbox.stub()
        };

    });

    afterEach(() => {
        sandbox.restore();
    });

    it('should log no Java file changes found when diff list is empty', () => {
        fsStub.readFileSync.returns('');

        const copyDiffFilesProxy = proxyquire('../src/copyDiffFiles', {
            'fs-extra': fsStub,
        }).copyDiffFiles;

        copyDiffFilesProxy('diffList.txt', 'source', 'target');

        expect(stepMock.info.calledOnceWith('Diff list is empty. No Java file changes found'));

    });

    it('should copy multiple files file when they exist in source directory', () => {
        fsStub.readFileSync.returns('src/main/java/com/example/MyClass1.java src/main/java/com/example/MyClass2.java');

        const copyDiffFilesProxy = proxyquire('../src/copyDiffFiles', {
            'fs-extra': fsStub,
        }).copyDiffFiles;

        copyDiffFilesProxy('diffList.txt', 'source', 'target');

        expect(fsStub.existsSync.calledWith(path.join('source', 'src/main/java/com/example/MyClass1.java'))).to.be.true;
        expect(fsStub.existsSync.calledWith(path.join('source', 'src/main/java/com/example/MyClass2.java'))).to.be.true;
        expect(fsStub.copyFileSync.calledTwice)
    });

    it('should handle subDir if it exists', () => {
        fsStub.readFileSync.returns('src/main/java/com/example/MyClass1.java src/main/java/com/example/MyClass2.java');

        const copyDiffFilesProxy = proxyquire('../src/copyDiffFiles', {
            'fs-extra': fsStub,
        }).copyDiffFiles;

        copyDiffFilesProxy('diffList.txt', 'source', 'target', 'src/main/');

        expect(fsStub.existsSync.calledWith(path.join('source', 'java/com/example/MyClass1.java'))).to.be.true;
        expect(fsStub.existsSync.calledWith(path.join('source', 'java/com/example/MyClass2.java'))).to.be.true;
        expect(fsStub.copyFileSync.calledTwice)
    });


    it('should copy file when it exists in source directory', () => {
        const copyDiffFilesProxy = proxyquire('../src/copyDiffFiles', {
            'fs-extra': fsStub,
        }).copyDiffFiles;

        copyDiffFilesProxy('diffList.txt', 'source', 'target');

        expect(fsStub.existsSync.calledWith(path.join('source', 'src/main/java/com/example/MyClass.java'))).to.be.true;
        expect(fsStub.copyFileSync.calledOnceWith(path.join('source', 'src/main/java/com/example/MyClass.java'), path.join('target', 'src/main/java/com/example/MyClass.java')))
    });

    it('should not copy file when it does not exist in source directory', () => {
        fsStub.existsSync.returns(false);

        const copyDiffFilesProxy = proxyquire('../src/copyDiffFiles', {
            'fs-extra': fsStub,
        }).copyDiffFiles;

        copyDiffFilesProxy('diffList.txt', 'source', 'target');

        expect(fsStub.copyFileSync.notCalled).to.be.true;
    });
});
